package com.slz3.business.generator;

import com.slz3.business.BusinessRouter;
import com.slz3.business.frame.util.HumpToUnderline;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;

/**
 * @auhtor buerjun
 * @date 2018-11-02
 * @desc 生成java module工具类
 */
public class WangErCloneTemplateGenerator {
    //对应BusinessRouter 中 路由常量字段,如果生成功能代码只需要改变这一个参数就行了
    private static final String STATIC_FIELD = "MEM_APP_KEY";
    private static String TARGET_CHILD_DIC = null;

    static {
        try {
            Field field = BusinessRouter.class.getDeclaredField(STATIC_FIELD);
            BusinessRouter router = BusinessRouter.class.newInstance();
            field.setAccessible(true);
            TARGET_CHILD_DIC = field.get(router).toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final String ROOT = System.getProperty("user.dir");
    public static final String JAVA_ROOT = "/src/main/java/";

    private static final Path SOURCE = Paths.get(
            ROOT + JAVA_ROOT + "com/slz3/business/module/templateExample/temStyle1");
    private static String TARGET = "com/slz3/business/module" + TARGET_CHILD_DIC;
    private static final Path TARGET_PATH = Paths.get(
            ROOT + JAVA_ROOT + TARGET);

    private static final Path SERVICES_PATH = Paths.get(ROOT + JAVA_ROOT + "com/slz3/business/frame/module/Services.java");
    private static final Path REPOSITORYS_PATH = Paths.get(ROOT + JAVA_ROOT + "com/slz3/business/frame/module/Repositorys.java");
    private static final Path ROUTER_PATH = Paths.get(ROOT + JAVA_ROOT + "com/slz3/business/BusinessRouter.java");

    String[] split = TARGET_CHILD_DIC.split("/");
    String first = split[1];
    String second = split[2];
    String firstCharUpper = String.valueOf(first.charAt(0)).toUpperCase() + first.substring(1);
    String secondCharUpper = String.valueOf(second.charAt(0)).toUpperCase() + second.substring(1);

    private String replaceTarToSou(String line) {
        return line.replace("TemplateExample", firstCharUpper)
                .replace("templateExample", first)
                .replace("template_example", HumpToUnderline.convert(first))
                .replace("template-example", HumpToUnderline.convert(first).replace("_", "-"))

                .replace("TemStyle1", secondCharUpper)
                .replace("temStyle1", second)
                .replace("tem_style1", HumpToUnderline.convert(second))
                .replace("tem-style1", HumpToUnderline.convert(second).replace("_", "-"))
                ;
    }

    public static void main(String[] args) throws Exception {
        WangErCloneTemplateGenerator generator = new WangErCloneTemplateGenerator();
        generator.execute();
        generator.updateServices();
        generator.updateRepositorys();
        generator.updateRouter();
    }

    //update Repositorys
    private void updateRepositorys() {
        //插入import
        String normalRepository = secondCharUpper + "Repository";
        String normalRepositoryPackage = TARGET.replace("/",".") + "." + "repository." + normalRepository;
        String importRepository = "import " + normalRepositoryPackage + ";";
        System.out.println(importRepository);


        //插入static field
        String staticNormalField = "    public static "+ normalRepository + " " + second +";";
        System.out.println(staticNormalField);

        //插入Autowired set
        String staticFieldSet = "\n    @Autowired\n" +
                "    public void set"+secondCharUpper+ "("+secondCharUpper+"Repository "+second+") {\n" +
                "        Repositorys."+second+" = "+second+";\n" +
                "    }";
        System.out.println(staticFieldSet);

        try {
            List<String> lines = Files.readAllLines(REPOSITORYS_PATH);
            List<String> targetLines = new ArrayList<>(lines.size());
            for (int i = 0; i < lines.size(); i++) {
                String line = lines.get(i);
                targetLines.add(line);
                if (line.contains("this line is work for import,don't remove")){
                    targetLines.add(importRepository);
                }
                if (line.contains("this line is work for static field,don't remove")){
                    targetLines.add(staticNormalField);
                }
                if (line.contains("this line is work for field set,don't remove")){
                    targetLines.add(staticFieldSet);
                }
            }
            Files.write(REPOSITORYS_PATH,targetLines);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //update Services
    private void updateServices() {
        //插入import
        String normalService = secondCharUpper + "Service";
        String normalServicePackage = TARGET.replace("/",".") + "." + "service." + normalService;
        String importNormalServicePackage = "import " + normalServicePackage + ";";
        System.out.println(importNormalServicePackage);
        String transactionalService = secondCharUpper + "TransactionalService";
        String transactionalServicePackage = TARGET.replace("/",".") + "." + "service." + transactionalService;
        String importTransactionalServicePackage = "import " + transactionalServicePackage + ";";
        System.out.println(importTransactionalServicePackage);

        //插入static field
        String staticNormalField = "    public static "+ normalService + " " + second +";";
        String staticTransactionalField = "    public static " + transactionalService + " " + second + "Transactional;";
        System.out.println(staticNormalField);
        System.out.println(staticTransactionalField);

        //插入Autowired set
        String staticFieldSet = "\n    @Autowired\n" +
                "    public void set"+secondCharUpper+ "("+secondCharUpper+"Service "+second+") {\n" +
                "        Services."+second+" = "+second+";\n" +
                "    }\n\n" +
                "    @Autowired\n" +
                "    public void set"+secondCharUpper+"Transactional("+secondCharUpper+"TransactionalService "+second+"Transactional) {\n" +
                "        Services."+second+"Transactional = "+second+"Transactional;\n" +
                "    }";
        System.out.println(staticFieldSet);

        try {
            List<String> lines = Files.readAllLines(SERVICES_PATH);
            List<String> targetLines = new ArrayList<>(lines.size());
            for (int i = 0; i < lines.size(); i++) {
                String line = lines.get(i);
                targetLines.add(line);
                if (line.contains("this line is work for import,don't remove")){
                    targetLines.add(importNormalServicePackage);
                    targetLines.add(importTransactionalServicePackage);
                }
                if (line.contains("this line is work for static field,don't remove")){
                    targetLines.add(staticNormalField);
                    targetLines.add(staticTransactionalField);
                }
                if (line.contains("this line is work for field set,don't remove")){
                    targetLines.add(staticFieldSet);
                }
            }
            Files.write(SERVICES_PATH,targetLines);

        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    //update Router
    private void updateRouter() {
        String router = secondCharUpper + "Router";
        String handler = secondCharUpper + "Handler";

        String routerPackage = TARGET.replace("/",".") + "." + router;
        String importRouterPackage = "import " + routerPackage + ";";
        String handlerPackage = TARGET.replace("/",".")+ "." + handler;
        String importHandlerPackage = "import " + handlerPackage + ";";
        String action = "    @Bean\n" +
                "    RouterFunction<ServerResponse> "+second+"("+secondCharUpper+"Handler handler){\n" +
                "        return nest(path("+STATIC_FIELD+"), "+secondCharUpper+"Router.funs(handler));\n" +
                "    }";

        try {
            List<String> lines = Files.readAllLines(ROUTER_PATH);
            List<String> targetLines = new ArrayList<>(lines.size());
            for (int i = 0; i < lines.size(); i++) {
                String line = lines.get(i);
                targetLines.add(line);
                if (line.contains("this line is work for import,don't remove")){
                    targetLines.add(importRouterPackage);
                    targetLines.add(importHandlerPackage);
                }
                if (line.contains("this line is work for router,don't remove")){
                    targetLines.add(action);
                }
            }
            Files.write(ROUTER_PATH,targetLines);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public boolean execute() throws Exception {
        // 1 遍历“模板根目录”下的每一个模板文件
        Files.walkFileTree(SOURCE, new CloneTemplateToTargetFileVisitor());
        return true;
    }

    /**
     * Created by jinxing on 2017/4/9. // 1 遍历“模板根目录”下的每一个模板文件 Files.walkFileTree(file, new
     * CloneTemplateToTargetFileVisitor());
     */
    class CloneTemplateToTargetFileVisitor extends SimpleFileVisitor<Path> {

        /**
         * 2.唯一要做的就是重写 visitFile，让它来为你工作；
         **/
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            // 3.过滤所有来源目录文件
            if (file.toString().endsWith(".java")
                    || file.toString().endsWith(".ts")
                    || file.toString().endsWith(".html")
                    || file.toString().endsWith(".proto")
                    || file.toString().endsWith(".jsp")
                    || file.toString().endsWith(".js")
                    || file.toString().endsWith(".css")) {
                // 来源目录文件绝对路径
                String souFileAbsDir = file.toString();
                System.out.println(souFileAbsDir);
                // 目标目录文件绝对路径 // 修改跟路径 // 修改文件名
                String tarFileAbsDir = replaceTarToSou(
                        souFileAbsDir.replace(SOURCE.toString(), TARGET_PATH.toString()));
                System.out.println(tarFileAbsDir);
                // [生成]目标目录 & 文件
                Path tarFolder = Paths
                        .get(tarFileAbsDir.substring(0, tarFileAbsDir.lastIndexOf(File.separator)));
                Path tarFile = Paths.get(tarFileAbsDir);
                if (Files.notExists(tarFolder)) {
                    Files.createDirectories(tarFolder);
                }
                if (Files.notExists(tarFile)) {
                    Files.createFile(tarFile);
                    // 写入
                    try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8);
                         BufferedWriter writer = Files.newBufferedWriter(tarFile, StandardCharsets.UTF_8,
                                 StandardOpenOption.WRITE)) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            writer.write(replaceTarToSou(line));
                            writer.write("\n");
                        }
                    }
                }
            }
            // 4.return
            return FileVisitResult.CONTINUE;
        }
    }

}
